package com.znsb.mxk.download;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.util.Log;
import android.widget.RemoteViews;

import org.xutils.common.Callback.Cancelable;
import org.xutils.common.Callback.ProgressCallback;
import org.xutils.http.RequestParams;
import org.xutils.x;

import java.io.File;

public class AppUpdateDownloadService extends Service implements UpdateAppBroadCastHandler.OnReceiveUpdateListener {

	public static final String fileDectoryName = "AppUpdate";// 文件夹名字
	/** app类型 **/
	public static final String APP_BASE_NAME = "appUpdate";// apk的基础文件名

	private final String TAG = "AppUpdateDownloadService";
	/* 标记是否正在下载更新 * */
	private boolean isDownloading = false;
	/** 通知id **/
	private int notificationId = 1546;
	private Notification notification;
	private NotificationManager notificationManager;
	private UpdateAppBroadCastHandler updateAppBroadCaseHandler;
	private UpdateAppBean updateAppBean;
	private Cancelable httpCancelable;

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		updateAppBroadCaseHandler = new UpdateAppBroadCastHandler(this, this);
		Log.d("tag","服务创建了。。。");
		registBroadCast();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.d("tag", "服务启动了。。。");
		return super.onStartCommand(intent, flags, startId);
	}

	/**
	 * 注册广播监听
	 */
	private void registBroadCast() {
		// 注册网络变化广播监听
		updateAppBroadCaseHandler.registerBroadCastReceiver(
				UpdateAppBroadCastHandler.UpdateAppConstant.NET_WORK_CHANGED_BROAD_CASE_ACTION);
		// 注册APP安装更新通知监听
		updateAppBroadCaseHandler.registerBroadCastReceiver(
				UpdateAppBroadCastHandler.UpdateAppConstant.NOTIFACTION_UPDATE_BROAD_CASE_ACTION);
		// 注册监听外部请求service下载状态监听
		updateAppBroadCaseHandler
				.registerBroadCastReceiver(UpdateAppBroadCastHandler.UpdateAppConstant.CHECK_SERVICE_STATE_ACTION);
		// 注册取消下载监听
		updateAppBroadCaseHandler
				.registerBroadCastReceiver(UpdateAppBroadCastHandler.UpdateAppConstant.CANCEL_UPDATE_SERVICE);
		// 暂停下载监听
		updateAppBroadCaseHandler
				.registerBroadCastReceiver(UpdateAppBroadCastHandler.UpdateAppConstant.PAUSE_UPDATE_SERVICE);
		// 暂停后重新下载监听
		updateAppBroadCaseHandler
				.registerBroadCastReceiver(UpdateAppBroadCastHandler.UpdateAppConstant.RESTART_UPDATE_SERVICE);
	}

	/**
	 * 准备下载或者安装
	 * 
	 * @param updateBean
	 */
	private void initDownloadOrInsertApk(UpdateAppBean updateBean) {
		if (updateAppBean == null || isDownloading) {// 正在下载
			return;
		}

		String appFileUrl = getSaveFilePath(getApkName(updateAppBean.getVersionCode()));
		File file = new File(appFileUrl);
		if (file.exists() && updateBean != null) {// 文件已经在本地保存
			if (updateBean.isAutoInstallOnDownloaded()) {// 设置了文件存在自动安装
				installApk();
			}
			return;
		}

		if (!isNetworkAvailable()) {// 网络不可用
			return;
		}

		if (updateBean.isUpdateInWifi() && !isWifi()) {// 设置了在WiFi下才更新，当前不是WiFi
			return;
		}

		clearApkFiles(new File(getAppDirectory()));// 将以前版本打apk文件删除
		// 准备开始下载
		String cachFilePath = getSaveFilePath(getCachFileName(updateAppBean.getVersionCode()));
		if (!TextUtils.isEmpty(cachFilePath)) {

			RequestParams requestParams = new RequestParams(updateBean.getUrl());
			requestParams.setSaveFilePath(cachFilePath);
			requestParams.setAutoRename(false);
			httpCancelable = x.http().get(requestParams, new MyProgressCallback());
		}
	}

	private class MyProgressCallback implements ProgressCallback<File> {

		@Override
		public void onCancelled(CancelledException arg0) {
			Log.d("tag", "onCancelled下载取消了");
			isDownloading = false;
		}

		@Override
		public void onError(Throwable arg0, boolean arg1) {
			Log.d("tag", "onFailure下载失败了"+arg0.getMessage());
			isDownloading = false;
			if (notificationManager != null) {
				notificationManager.cancel(notificationId);
			}
		}

		@Override
		public void onFinished() {

		}

		@Override
		public void onSuccess(File arg0) {
			Log.d("tag", "onSuccess下载成功了");
			isDownloading = false;
			if (notificationManager != null) {
				notificationManager.cancel(notificationId);
			}

			if (updateAppBean != null) {
				File file = new File(getSaveFilePath(getApkName(updateAppBean.getVersionCode())));
				if (file.exists()) {
					file.delete();
				}
			}
			if (updateAppBean != null) {
				// 下载完后重命名
				File fileApp = new File(getSaveFilePath(getCachFileName(updateAppBean.getVersionCode())));
				// 将下载后的缓存apk名字重命名为能够安装的apk文件名
				fileApp.renameTo(new File(getSaveFilePath(getApkName(updateAppBean.getVersionCode()))));
			}
			// 删除以前版本失败时的缓存文件
			clearCacheFiles(new File(getAppDirectory()));
			if (updateAppBean != null && updateAppBean.isAutoInstallOnDownloaded()) {
				installApk();
			}
		}

		@Override
		public void onLoading(long total, long current, boolean arg2) {
			Log.d("tag", "total=" + total + "  current=" + current + "   百分比=" + 100 * current / total + "%");
			// 通知外部进度更新
			if (updateAppBean != null && updateAppBean.isSendDownloadProgress()) {
				updateAppBroadCaseHandler.sendProgressChangedBroadCaset(current, total);
			}
			// 更新notification的进度
			if (updateAppBean != null && updateAppBean.isShowLoadingNotifiaction()) {
				updateProgress((int) current, (int) total, 100 * current / total + "%");
			}
		}

		@Override
		public void onStarted() {
			Log.d("tag", "onStart下载开始了");
			isDownloading = true;
			if (updateAppBean != null && updateAppBean.isShowLoadingNotifiaction()) {
				setNotifiction();
			}
			Log.d("tag", "onStart");
		}

		@Override
		public void onWaiting() {

		}

	}

	/**
	 * 删除文件夹里面的apk文件
	 * 
	 * @param
	 *
	 */
	private void clearApkFiles(File fileDirectory) {
		if (fileDirectory.exists() && fileDirectory.isDirectory()) {
			String[] list = fileDirectory.list();
			for (int i = 0; i < list.length; i++) {
				String name = list[i];
				if (!TextUtils.isEmpty(name) && name.indexOf(".apk") != -1) {
					File f = new File(fileDirectory.getPath() + File.separator + name);
					f.delete();
				}
			}
		}
	}

	/**
	 * 删除文件夹里面的cache文件
	 * 
	 * @param
	 *
	 */
	private void clearCacheFiles(File fileDirectory) {
		if (fileDirectory.exists() && fileDirectory.isDirectory()) {
			String[] list = fileDirectory.list();
			for (int i = 0; i < list.length; i++) {
				String name = list[i];
				if (!TextUtils.isEmpty(name) && name.indexOf(".cacheApk") != -1) {
					File f = new File(fileDirectory.getPath() + File.separator + name);
					f.delete();
				}
			}
		}
	}

	/**
	 * 设置并开启通知
	 */
	private void setNotifiction() {
		notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
		notification = new Notification(R.mipmap.ic_launcher, "下载更新", System.currentTimeMillis());
		notification.contentView = new RemoteViews(getPackageName(), R.layout.update_notification_progress);
		Intent intent = new Intent(UpdateAppBroadCastHandler.UpdateAppConstant.CANCEL_UPDATE_SERVICE);
		PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1345, intent, PendingIntent.FLAG_UPDATE_CURRENT);
		notification.contentView.setOnClickPendingIntent(R.id.tv_cancel, pendingIntent);
		notificationManager.notify(notificationId, notification);
	}

	/**
	 * 更新进度条
	 * 
	 * @param currentProgress
	 * @param max
	 */
	private void updateProgress(int currentProgress, int max, String progress) {
		if (notification == null) {
			setNotifiction();
		}
		if (notification != null && notification.contentView != null && notificationManager != null) {
			notification.contentView.setProgressBar(R.id.progress_bar, max, currentProgress, false);
			notification.contentView.setTextViewText(R.id.tv_progress_number, progress);
			notificationManager.notify(notificationId, notification);
		}
	}

	/**
	 * 获取文件保存具体地址
	 * 
	 * @param fileName
	 * @return
	 */
	private String getSaveFilePath(String fileName) {
		return getAppDirectory() + File.separator + fileName;
	}

	/**
	 * 获取app保存文件目录
	 * 
	 * @return
	 */
	private String getAppDirectory() {
		if (isCanUseSD()) {
			return Environment.getExternalStorageDirectory() + File.separator + fileDectoryName + File.separator
					+ APP_BASE_NAME;
		} else {
			return null;
		}
	}

	public boolean isCanUseSD() {
		try {
			return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * * 生成apk名
	 * 
	 * @return 客户端类型名+版本code+.apk
	 */
	private String getApkName(int versionCode) {
		String apkName = null;
		if (versionCode == -1) {
			// 设置新版本的版本号 在服务器没有返回的情况下默认为当前版本号+1;
			versionCode = getVerisonCode() + 1;
		}
		apkName = APP_BASE_NAME + versionCode + ".apk";
		return apkName;
	}

	/**
	 * 获取下载时缓存的名字
	 * 
	 * @return
	 */
	private String getCachFileName(int versionCode) {
		String cachName = null;
		if (versionCode == -1) {
			// 设置新版本的版本号 在服务器没有返回的情况下默认为当前版本号+1;
			versionCode = getVerisonCode() + 1;
		}
		cachName = APP_BASE_NAME + versionCode + ".cacheApk";
		return cachName;
	}

	/**
	 * 获取应用当前版本号
	 * 
	 * @return
	 */
	private int getVerisonCode() {
		int versionCode = 1;
		try {
			PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
			versionCode = packageInfo.versionCode;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return versionCode;
	}

	/**
	 * 安装apk
	 */
	private void installApk() {
		if (updateAppBean == null) {
			return;
		}
		String appFileUrl = getSaveFilePath(getApkName(updateAppBean.getVersionCode()));
		Log.d("tag", "file=" + appFileUrl);
		if (!TextUtils.isEmpty(appFileUrl)) {
			File file = new File(appFileUrl);
			if (file.exists()) {
				Intent intent = new Intent();
				if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
					intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
					Uri contentUri = FileProvider.getUriForFile(this, "com.znsb.mxk.fileprovider", file);
					intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
				} else {
					intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
					intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				}
//				intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				intent.setAction(Intent.ACTION_VIEW);
//				intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
				startActivity(intent);
			}
			stopSelf();// 关闭service
		}
	}

	/**
	 * @return 检测网络是否可用
	 */
	private boolean isNetworkAvailable() {
		ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
		if (connectivityManager == null) {
			return false;
		} else {
			NetworkInfo[] networkInfo = connectivityManager.getAllNetworkInfo();
			if (networkInfo != null && networkInfo.length > 0) {
				for (int i = 0; i < networkInfo.length; i++) {
					// 判断当前网络状态是否为连接状态
					if (networkInfo[i].getState() == NetworkInfo.State.CONNECTED) {
						return true;
					}
				}
			}
		}
		return false;
	}

	private boolean isWifi() {
		ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
		if (activeNetInfo != null && activeNetInfo.getType() == ConnectivityManager.TYPE_WIFI) {
			return true;
		}
		return false;
	}

	/**
	 * 接收到更新通知
	 */
	@Override
	public void onReceiveUpdateApp(UpdateAppBean updateBean) {
		Log.d("tag", "接收到更新广播了。。。");
		updateAppBean = updateBean;
		if (updateBean != null && !TextUtils.isEmpty(updateBean.getUrl())) {
			initDownloadOrInsertApk(updateBean);
		}
	}

	/**
	 * 网络发生变化了
	 */
	@Override
	public void onReceiveNetWorkChanged() {
		Log.d("tag", "网络发生变化了。。。");
		// 当只在wifi下才更新时 当wifi中断 停止下载
		if (isDownloading && updateAppBean != null && isNetworkAvailable() && updateAppBean.isUpdateInWifi()
				&& !isWifi()) {
			if (notificationManager != null) {
				notificationManager.cancel(notificationId);
			}
			if (httpCancelable != null) {
				Log.d("tag", "wifi中断，只在wifi下下载暂停。。。");
				isDownloading = false;
				httpCancelable.cancel();
			}
		}
		// 在wifi下前面下载中断了重新开始下载
		if (!isDownloading && updateAppBean != null && isNetworkAvailable() && isWifi()) {
			initDownloadOrInsertApk(updateAppBean);
		}
		// 前面下载被中断 网络重连后不是wifi 但是用户设置的是在数据流量下下载 继续下载
		if (!isDownloading && updateAppBean != null && isNetworkAvailable() && !isWifi()
				&& !updateAppBean.isUpdateInWifi()) {
			initDownloadOrInsertApk(updateAppBean);
		}
	}

	/**
	 * 外部请求service状态监听
	 */
	@Override
	public void onReceiveRequestServiceStatus() {
		boolean fileExits = false;
		if (updateAppBean != null) {
			String filePath = getSaveFilePath(getApkName(updateAppBean.getVersionCode()));
			if (!TextUtils.isEmpty(filePath)) {
				File file = new File(filePath);
				fileExits = file.exists();
			}
		}
		// 是否是在后台静默下载更新（当设置了 下载后不自动安装、下载时在通知栏不提示进度、下载时不监听下载进度就认为属于静默下载）
		boolean isAutoRunning = false;
		if (updateAppBean != null) {
			if (!updateAppBean.isAutoInstallOnDownloaded() && !updateAppBean.isSendDownloadProgress()
					&& !updateAppBean.isShowLoadingNotifiaction()) {
				isAutoRunning = true;
			}
		}
		// 将下载状态发送出去
		if (updateAppBroadCaseHandler != null) {
			updateAppBroadCaseHandler.sendBroadCaseServiceDownloadStatus(isDownloading, fileExits, isAutoRunning);
		}

	}

	@Override
	public void onReceiveServiceStatus(boolean isDownloading, boolean appFileIsExists, boolean isAutoRunning) {

	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		updateAppBroadCaseHandler.unRegisterReceiver();
		if (notificationManager != null) {
			notificationManager.cancel(notificationId);
		}
	}

	@Override
	public void onReviceProgressChanged(long current, long total) {
	}

	@Override
	public void onReviceCancelUpdate() {
		Log.d("tag", "service接收到取消下载请求");
		if (notificationManager != null) {
			notificationManager.cancel(notificationId);
		}
		if (isDownloading && httpCancelable != null && !httpCancelable.isCancelled()) {
			httpCancelable.cancel();
			updateAppBean = null;// 在接收到用户取消指令后直接关闭下载
			stopSelf();
		}
	}

	@Override
	public void onRevicePauseUpdate() {
		Log.d("tag", "service接收到暂停下载请求");
		if (isDownloading && httpCancelable != null && !httpCancelable.isCancelled()) {
			httpCancelable.cancel();
		}
	}

	@Override
	public void onReviceRestartUpdate() {
		Log.d("tag", "service接收到重新下载请求");
		if (!isDownloading && httpCancelable != null && updateAppBean != null) {
			initDownloadOrInsertApk(updateAppBean);
		}
	}

}
